<template>
    <div class="loginBox">
        <!-- <a class="login_logo"></a> -->
        <div class="midgroup">
            <div class="loginwrap loginwarrp">
                <div class="logingroup login_form">
                    <h2 style="text-align: center; color: #2fa7b9;">注 册</h2>
                    <el-form ref="ruleFormRef" :model="state.ruleForm" status-icon :rules="rules" label-width="120px"
                        style="padding-top:20px;" label-position="top" size="large" class="demo-ruleForm">
                        <el-form-item prop="registerName">
                            <el-input :prefix-icon="User" v-model="state.ruleForm.registerName" placeholder="请输入用户名" />
                        </el-form-item>
                        <el-form-item prop="registerEmail">
                            <el-input :prefix-icon="Message" v-model="state.ruleForm.registerEmail"
                                placeholder="请输入电子邮箱" />
                        </el-form-item>
                        <el-form-item prop="registerPass">
                            <el-input :prefix-icon="Lock" v-model="state.ruleForm.registerPass" show-password
                                autocomplete="off" placeholder="请输入密码" />
                        </el-form-item>
                        <el-form-item prop="inputVerificationCode">
                            <el-input :prefix-icon="Right" v-model="state.ruleForm.inputVerificationCode"
                                placeholder="邮箱验证码">
                                <template #append>
                                    <input type="button" :plain="true" @click="getCode()" :disabled="!state.show"
                                        style="width: 100%;height: 100%;border: 0px;background: none;width: 70px;color: #ababab;"
                                        :value="state.codeText" />
                                </template>
                            </el-input>
                        </el-form-item>
                        <el-form-item prop="loginBtn" class="loginBtn">
                            <el-button color="#2fa7b9" plain style="width:100%;"
                                @click="submitAddRegisterInfo(ruleFormRef)">立即注册
                            </el-button>
                        </el-form-item>
                        <p style="font-size: 12px; text-align: center;color:#999;">
                            已有账号，
                            <!-- <a href="/login" style="color:#2fa7b9;">立即登录</a> -->
                            <router-link style="color:#2fa7b9;" :to="{name:'login'}">立即登录</router-link>
                        </p>
                    </el-form>

                    <footer style="text-align:center;">
                        <p>若没有坚持到底的勇气,还是不要开始好了.</p>
                    </footer>
                </div>
            </div>
        </div>
        <div class="footer_copyright">
            <p>
                · Designed by 小李. All Rights Reserved. Copyright © 2022 小李 ·
            </p>
        </div>
    </div>
</template>

<script setup lang="ts">
import {
    reactive,
    ref,
} from 'vue'

import {
    User,
    Lock,
    Right,
    Message
} from '@element-plus/icons-vue'
import {
    useRouter
} from 'vue-router';
import {
    ElMessage,
    ElLoading,
    ElNotification
} from 'element-plus'
import { CheckUserName, CheckUserEmail, Register, SendEmail } from "@/api/foreground";
import type { FormInstance } from 'element-plus'
import { validate } from '@/utils/validate'
const router = useRouter();
const ruleFormRef = ref<FormInstance>()
// 获取验证码60秒倒计时
const TIME_COUNT = 60;
// 3分钟=180秒，三分钟后清除验证码
const TIME_CLEAR_COUNT = 180;
let timer: any = null
const state = reactive({
    ruleForm: {
        registerName: '',
        registerEmail: '',
        registerPass: '',
        // 随机生成的验证码
        verificationCode: '',
        // 输入的验证码
        inputVerificationCode: ''
    },
    //获取当前访问的协议/:IP/端口
    // loginUrl: location.protocol + '//' + location.host + '/' + 'login.html',
    // 获取验证码 点击后为禁止状态
    show: true,
    // 获取验证码的文字 点击后改变
    codeText: '获取验证码',
    // 当前秒数
    count: 0,
    // 时间  计时器
    // 存放生成的六位随机数   验证码
    code: '',
    // 三分钟后清除验证码,计时器
    clearCount: "",
    // 点击发送验证码，再进行验证验证码输入框
    affirmGet: false
})

// 用户名的非空、正则验证
const validateName = (rule: unknown, value: string | undefined, callback: (msg?: string) => void) => {
    if (!value) {
        return callback('请填写此字段~')
    } else {
        if (!validate.nameGrep.test(value)) {
            callback('用户名由2~8位中英文、数字、下划线组成');
        } else {
            let params = {
                registerName: value
            };
            CheckUserName(params).then((res) => {
                if (res.code == 1020) {
                    callback('此用户名已被注册，请更换一个');
                } else {
                    callback()
                }
            })
        }
    }
}
// 密码的非空验证
const validatePass = (rule: unknown, value: string | undefined, callback: (msg?: string) => void) => {
    if (!value) {
        return callback('请填写此字段~')
    } else {
        if (!validate.passGrep.test(value)) {
            callback('密码6~18位字母、数字、特殊字符组成')
        } else {
            callback()
        }
    }
}
// 邮箱的非空验证
const validateEmail = (rule: unknown, value: string | undefined, callback: (msg?: string) => void) => {
    if (!value) {
        return callback('请填写此字段~')
    } else {
        if (!validate.emailGrep.test(value)) {
            callback('请按照正确的邮箱格式输入');
        } else {
            let params = {
                registerEmail: value
            };
            CheckUserEmail(params).then((res) => {
                if (res.code == 1021) {
                    callback('此邮箱已被注册，请更换一个');
                } else {
                    callback()
                }
            })
        }
    }
}

// 验证码的非空、输入正确验证
const validateVerificationCode = (rule: unknown, value: string | undefined, callback: (msg?: string) => void) => {
    // 判断邮箱的正则是否通过，没有通过则先不验证此字段
    ruleFormRef.value?.validateField('registerEmail', err => {
        if (err) {
            if (state.affirmGet) {
                if (!value) {
                    return callback('请填写此字段~')
                } else {
                    // 输入的验证码正确
                    if (value != state.code) {
                        return callback('验证码有误，请重新输入')
                    } else {
                        callback()
                    }
                }
            } else {
                if (!value) {
                    return callback('获取验证码，填写此字段~')
                }
            }
        }
    })
}
const rules = reactive({
    registerName: [{
        validator: validateName,
        trigger: 'blur'
    }],
    registerPass: [{
        validator: validatePass,
        trigger: 'blur'
    }],
    registerEmail: [{
        validator: validateEmail,
        trigger: 'blur'
    }],
    inputVerificationCode: [{
        validator: validateVerificationCode,
        trigger: 'blur'
    }],
})

// 确认好获取验证码的邮箱，防止获取后修改，修改则本次验证码立即失效
let affirmEmail = "";
// 获取验证码 
const getCode = () => {
    // 点击发送验证码，再进行验证验证码输入框
    state.affirmGet = true
    // 判断邮箱的正则是否通过
    ruleFormRef.value?.validateField('registerEmail', err => {
        if (err) {
            // 获取验证码，将当前表单中的邮箱号保存
            affirmEmail = state.ruleForm.registerEmail
            // 生成六位数随机验证码发送给后台
            state.code = '';
            for (var i = 0; i < 6; i++) {
                state.code += Math.floor(Math.random() * 10);
            }
            // 将验证码、用户输入的邮箱传给后台，发送给用户邮箱
            const params = {
                registerEmail: state.ruleForm.registerEmail, // 用户当前邮箱
                content: `【小李博客】验证码:${state.code},请勿将验证码告知他人,有效期3分钟,请妥善保管。`
            }
            SendEmail(params).then((res) => {
                if (res.code === 0) {
                    // 点击后倒计时60秒
                    if (!timer) {
                        state.count = TIME_COUNT;
                        state.show = false;
                        timer = setInterval(() => {
                            if (state.count > 0 && state.count <= TIME_COUNT) {
                                if (state.ruleForm.registerEmail ===
                                    affirmEmail) {
                                    state.count--;
                                    state.codeText = state.count + 's';
                                } else {
                                    state.show = true;
                                    window.clearInterval(timer);
                                    timer = null;
                                    state.codeText = "获取验证码";
                                    affirmEmail = "";
                                    state.code = "";
                                }
                            } else {
                                state.show = true;
                                window.clearInterval(timer);
                                timer = null;
                                state.codeText = "重新获取";
                                affirmEmail = ""
                            }
                        }, 1000)
                    }
                } else {
                    ElMessage.error('验证码获取失败.')
                }
            })
        } else {
            ElMessage.error('按要求填写电子邮箱后再获取验证码.')
            return false;
        }
    });

}

// 立即注册按钮
const submitAddRegisterInfo = (formEl: FormInstance | undefined) => {
    // 1：校验注册信息  validate
    if (!formEl) return
    formEl.validate((valid) => {
        // 如果表单校验成功 提交数据到后台
        if (valid) {
            const data = {
                userName: state.ruleForm.registerName,
                userPass: state.ruleForm.registerPass,
                userEmail: state.ruleForm.registerEmail,
            }
            Register(data).then((res) => {
                // 加载动画
                const loading = ElLoading.service({
                    lock: true,
                    text: 'Loading',
                    background: 'rgba(0, 0, 0, 0.7)',
                })
                if (res.code === 0) {
                    loading.close()
                    ElNotification({
                        title: '注册成功',
                        message: '登录即可访问博客后台.',
                        type: 'success',
                    })
                    router.push({
                        path: '/login',
                    });
                } else {
                    // 注册失败
                    ElNotification({
                        title: 'Error',
                        message: '注册失败.',
                        type: 'error',
                    })
                }
                // 重置表单项，将其值重置为初始值，并移除校验结果
                formEl.resetFields()
                state.show = true;
                window.clearInterval(timer);
                timer = null;
                state.codeText = "获取验证码";
                affirmEmail = "";
                state.code = "";
            })
        }
    })
}
</script>

<style scoped>
.loginBox {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    background: #fff url(../../assets/login/login-bg.png) no-repeat;
    background-size: cover;
}

.login_logo {
    display: block;
    position: absolute;
    left: 8vw;
    top: 20px;
    width: 160px;
    height: 50px;
    background: url(../../assets/logo.svg) no-repeat center;
    background-size: 160px;
}

.loginBox .midgroup {
    width: 420px;
    margin: 20vh auto;
    position: relative;
}

.loginBox .midgroup .logingroup {
    padding: 20px 40px;
    background: white;
    overflow: hidden;
    box-shadow: 0 1px 10px 0 rgb(7 17 27 / 10%);
    padding-top: 20px;
    border-radius: 10px;
}

.loginBox .midgroup .logingroup footer {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px dotted #ddd;
    color: #999;
    font-size: 12px;
    overflow: hidden;
}

.footer_copyright {
    width: 100%;
    text-align: center;
    line-height: 24px;
    color: #999;
    font-size: 12px;
    position: fixed;
    left: 0;
    bottom: 0;
    overflow: hidden;
    padding: 10px;
    border-top: 1px solid #eee;
    background: white;
}


:global(.el-input-group__append) {
    padding: 0px 10px;
    background: #f6f6f6;
}

.loginBtn :deep(.el-form-item__error) {
    text-align: center;
    width: 100%;
}
</style>